package com.sy.module_clockin.view

import android.animation.ObjectAnimator
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.LinearInterpolator
import androidx.core.content.res.use
import com.blankj.utilcode.util.LogUtils
import com.sy.module_clockin.R
import com.sy.module_clockin.recycler.dp2px
import kotlin.math.cos
import kotlin.math.sin


class ClockInProgressView : View {
    private val TAG = "ClockInProgressView"

    private var mWidth = 0f
    private var mHeight = 0f

    /**
     * 第一次加载动画
     */
    private var isFisrtShowAnimate = false

    /**
     * 设计图宽
     */
    private val defaultWidth by lazy { context.dp2px(375f) }

    /**
     * 缩放，按设计图宽来计算 mWidth/defaultWidth
     */
    private var scale = 1f

    /**
     * 进度条宽
     */
    private var progressWidth = 0f

    private var progressBgWidth = 0f

    private var lineMarginWidth = 0f

    /**
     * 进度条颜色
     */
    private var progressStartColor = 0
    private var progressEndColor = 0

    /**
     * 进度条背景颜色
     */
    private var progressBackgroundColor = 0

    /**
     * 扇形进度
     */
    private val progressRectF = RectF()

    /**
     * 打卡时间
     */
    private var clockInTime = 0

    /**
     * 圆弧渐变
     */
    private var sweepGradient: SweepGradient? = null
    private val sweepMatrix = Matrix()


    /**
     * 进度条画笔
     */
    private var progressPaint: Paint = Paint().apply {
        style = Paint.Style.STROKE
        isAntiAlias = true
        strokeCap = Paint.Cap.ROUND
    }

    /**
     * 进度点画笔
     */
    private var progressDotPaint: Paint = Paint().apply {
        style = Paint.Style.FILL
        isAntiAlias = true
        strokeCap = Paint.Cap.ROUND
    }

    private var progressAnimation: ObjectAnimator? = null

    /**
     * 中心点
     */
    private val centerPoinF = PointF()

    /**
     * 当前进度点
     */
    private val currentPoinF = PointF()


    constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : this(context, attrs, defStyleAttr, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {
        context.obtainStyledAttributes(attrs, R.styleable.ClockInProgressView).use { attr ->
            progressBgWidth = attr.getDimension(R.styleable.ClockInProgressView_progressBgWidth, context.dp2px(1f))
            progressWidth = attr.getDimension(R.styleable.ClockInProgressView_progressWidth, context.dp2px(3f))
            progressBackgroundColor = attr.getColor(R.styleable.ClockInProgressView_progressBackgroundColor, 0XFFD8DCE6.toInt())
            progressStartColor = attr.getColor(R.styleable.ClockInProgressView_progressStartColor, 0XFF91D425.toInt())
            progressEndColor = attr.getColor(R.styleable.ClockInProgressView_progressEndColor, 0XFF17A83E.toInt())
            clockInTime = attr.getInt(R.styleable.ClockInProgressView_clockInTime, 6)
        }
    }


    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {

        mWidth = MeasureSpec.getSize(widthMeasureSpec).toFloat()
        scale = mWidth / defaultWidth
        mHeight = mWidth

        setMeasuredDimension(mWidth.toInt(), mHeight.toInt())
        Log.d(TAG, "测量==》 缩放：${scale}  宽:${mWidth}  高:${mHeight}")
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)

        centerPoinF.x = mWidth / 2f
        centerPoinF.y = mHeight / 2f

        lineMarginWidth = context.dp2px(10) * scale

        initGradient()

    }

    private fun initGradient() {
        sweepGradient = SweepGradient(centerPoinF.x, centerPoinF.y, intArrayOf(progressStartColor, progressEndColor), null)
        sweepMatrix.setRotate(270f, centerPoinF.x, centerPoinF.y)
        sweepGradient?.setLocalMatrix(sweepMatrix)
    }

    override fun onDraw(canvas: Canvas) {
        if (canvas != null) {
            super.onDraw(canvas)
        }
        canvas?.apply {

            val marginW = progressWidth * scale * 5
            progressDotPaint.color = 0X33000000
            drawLine(marginW + lineMarginWidth, centerPoinF.y, mWidth - marginW - lineMarginWidth, centerPoinF.y, progressDotPaint)
            drawLine(centerPoinF.x, marginW + lineMarginWidth, centerPoinF.x, mHeight - marginW - lineMarginWidth, progressDotPaint)


            progressDotPaint.color = 0XE5FFFFFF.toInt()
            drawCircle(centerPoinF.x, centerPoinF.y, centerPoinF.x - marginW - lineMarginWidth * 2, progressDotPaint)


            progressPaint.strokeWidth = progressBgWidth * scale
            progressPaint.color = progressBackgroundColor
            progressPaint.shader = null
            drawCircle(centerPoinF.x, centerPoinF.y, centerPoinF.x - marginW, progressPaint)


            progressPaint.color = progressEndColor
            progressPaint.strokeWidth = progressWidth * scale
            progressRectF.top = marginW
            progressRectF.bottom = mHeight - marginW
            progressRectF.left = marginW
            progressRectF.right = mWidth - marginW

            progressPaint.shader = sweepGradient
            val calcSweAngle = calcSweAngle()
            drawArc(progressRectF, -90f, calcSweAngle, false, progressPaint)

            progressDotPaint.color = Color.WHITE
            calcNewPoint(calcSweAngle)
            drawCircle(currentPoinF.x, currentPoinF.y, progressWidth * scale * 4, progressDotPaint)
            progressDotPaint.color = progressEndColor
            drawCircle(currentPoinF.x, currentPoinF.y, progressWidth * scale * 2, progressDotPaint)
        }
    }

    /**
     * 计算旋转角度后新点的坐标
     */
    private fun calcNewPoint(angle: Float) {
        //将角度转为弧度
        val radian = angle * Math.PI / 180f

        //计算弧度的余弦值
        val cosv = cos(radian)
        //计算弧度的正弦值
        val sinv = sin(radian)

        currentPoinF.x = ((centerPoinF.x - centerPoinF.x) * cosv - (progressWidth * scale * 5 - centerPoinF.y) * sinv + centerPoinF.x).toFloat()
        currentPoinF.y = ((centerPoinF.x - centerPoinF.x) * sinv + (progressWidth * scale * 5 - centerPoinF.y) * cosv + centerPoinF.y).toFloat()
    }

    fun startAnimate(ctime: Int) {
        setClockInTime(ctime)
        if (!isFisrtShowAnimate) {
            isFisrtShowAnimate = true
            progressAnimation = ObjectAnimator.ofInt(this, "clockInTime", minOf(0, clockInTime), maxOf(0, clockInTime))?.apply {

                duration = 500 // 动画执行时间
                /*
                 * AccelerateInterpolator　　　　　                  加速，开始时慢中间加速
                 * DecelerateInterpolator　　　 　　                 减速，开始时快然后减速
                 * AccelerateDecelerateInterolator　                     先加速后减速，开始结束时慢，中间加速
                 * AnticipateInterpolator　　　　　　                 反向 ，先向相反方向改变一段再加速播放
                 * AnticipateOvershootInterpolator　                 反向加超越，先向相反方向改变，再加速播放，会超出目的值然后缓慢移动至目的值
                 * BounceInterpolator　　　　　　　                        跳跃，快到目的值时值会跳跃，如目的值100，后面的值可能依次为85，77，70，80，90，100
                 * CycleIinterpolator　　　　　　　　                   循环，动画循环一定次数，值的改变为一正弦函数：Math.sin(2 *
                 * mCycles * Math.PI * input) LinearInterpolator　　　 线性，线性均匀改变
                 * OvershottInterpolator　　　　　　                  超越，最后超出目的值然后缓慢改变到目的值
                 * TimeInterpolator　　　　　　　　　                        一个接口，允许你自定义interpolator，以上几个都是实现了这个接口
                 */
                interpolator = LinearInterpolator()
                start()
            }
        }
    }

    /**
     * 计算进度弧度
     */
    private fun calcSweAngle(): Float {
        var hour = clockInTime
        if (hour > 12) {
            hour -= 12
        }
        return hour / 12f * 360
    }


    fun setClockInTime(ctime: Int) {
        if (clockInTime == ctime) {
            return
        }

        clockInTime = ctime
        if (clockInTime > 12) {
            clockInTime -= 12
        }

        postInvalidate()
    }

    fun setProgressBgWidth(progressBgWidth: Float) {
        this.progressBgWidth = progressBgWidth
        postInvalidate()
    }

    fun setProgressWidth(progressWidth: Float) {
        this.progressWidth = progressWidth
        postInvalidate()
    }

    fun setProgressBackgroundColor(progressBackgroundColor: Int) {
        this.progressBackgroundColor = progressBackgroundColor
        postInvalidate()
    }


    fun setProgressColor(progressColors: IntArray) {
        if (progressColors.isEmpty()) return

        progressStartColor = progressColors[0]
        progressEndColor = if (progressColors.size > 1) {
            progressColors[1]
        } else {
            progressColors[0]
        }
        initGradient()
        postInvalidate()
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        progressAnimation?.cancel()
    }
}